iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0
自我挑戰組

解三十天的 CodeWars系列 第 11

Directions Reduction

  • 分享至 

  • xImage
  •  

CodeWars 題目

Link

難度

5 kyu

題目

刪除陣列中沒必要的相反方向;
例如往北走後又往南;往西走後又往東。

思路

驗證陣列元素是否有前後衝突。
如果有衝突就過濾掉目前迭代的元素,以及下一個。

pseudo code

for loop i < arr.legnth
if(arr[i] == "") target = "..."
if(arr[i+1] === target) delete arr[i+1]

else
i++

for loop end
return arr;

實作

function dirReduc(arr) {
   let target;
   let now = 0;
   while (now < arr.length) {
      if (arr[now] == "NORTH") target = "SOUTH";
      if (arr[now] == "SOUTH") target = "NORTH";
      if (arr[now] == "EAST") target = "WEST";
      if (arr[now] == "WEST") target = "EAST";
      if (arr[now + 1] === target) {
         arr.splice(now + 1, 1);
         arr.splice(now, 1);
         return dirReduc(arr);
      }
      now++;
   }
   return arr;
}

target 紀錄目前方向不應該走的,例如東紀錄西。

now 代表從起點開始 while 迴圈,前往陣列一個個的方向;並且依照目前要前往的位置,改動 target 的內容,並且比對下一位 now+1 是否與 target 相同。

如果相同:
刪除目前的所在位置、以及下一個要前進的方向;用遞迴的方式呼叫,並且帶入被改動後的陣列。
如果不同:表示目前方向沒有問題,now++ 前進。

最後返回 arr 的結果。

他人的解法

function dirReduc(plan) {
  var opposite = {
    'NORTH': 'SOUTH', 'EAST': 'WEST', 'SOUTH': 'NORTH', 'WEST': 'EAST'};
  return plan.reduce(function(dirs, dir){
      if (dirs[dirs.length - 1] === opposite[dir])
        dirs.pop();
      else
        dirs.push(dir);
      return dirs;
    }, []);
}

opposite 直接紀錄衝突的位置。
用 reduce 迭代路線,起始值會傳入一個空陣列。

如果被累加值的最後尾存在衝突,就從 dirs 刪除掉元素;否則 push 目前的元素。
最後把 dirs 返回給下一輪,直到跑完迴圈。

以傳入參數為:["NORTH", "SOUTH", "SOUTH", ...] 為例拆解 reduce 幾個步驟。

  1. 第一步 dirs 會帶入 reduce 的第二參數,也就是 []
  2. dirs 為 [],dir 為 NORTH 對應 opposite 的 SOUTH。
  3. 目前 dirs 最後位是不是 SOUTH?不是,dirs push 變成 ["NORTH"]
  4. 第二步 dirs 為 ["NORTH"],dir 為 SOUTH 對應 opposite 的 NORTH。
  5. 目前 dirs 最後位是不是 NORTH?是,dirs 移除後變成 []

依此類推。

心得

我通常在解完題之後都會看一下最佳解,所以也才在鐵人賽放到文章裡記錄下來。
本次的最佳解 reduce 的運用方式,也讓我學到了一種思路~


上一篇
A Man and his Umbrellas
下一篇
Mean Square Error
系列文
解三十天的 CodeWars30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言